package com.hunttown.mes.manage.controller._basic;

import com.hunttown.mes.rpc.domain.WorkflowBusinessUserRelDTO;
import com.hunttown.mes.rpc.domain.enums.workflow.*;
import com.hunttown.mes.rpc.domain.query.WorkflowBusinessDTOQuery;
import com.hunttown.mes.rpc.domain.query.WorkflowBusinessUserRelDTOQuery;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.common.OperateCode;
import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.manage.controller.common.ModelService;
import com.hunttown.mes.rpc.domain.AnalysisManageDTO;
import com.hunttown.mes.rpc.domain.WorkflowBusinessDTO;
import com.hunttown.mes.rpc.domain.WorkflowBusinessNodeDTO;
import com.hunttown.mes.rpc.domain.query.WorkflowBusinessNodeDTOQuery;
import com.hunttown.mes.common.utils.JSONUtils;
import com.hunttown.mes.common.utils.StringUtils;
import com.hunttown.mes.manage.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

import static com.hunttown.mes.common.utils.PageUtils.PagePackage;

/**
 * @title: 流程业务节点
 * @author: wangjunfu
 * @date: 2019-08-01 16:55:14
 * @description:
 */
@Controller
@RequestMapping(value = "/basic/wfbusiness-node")
public class WFBusinessNodeController {

    private final static Logger logger = LoggerFactory.getLogger(WFBusinessNodeController.class);

    private final WorkflowBusinessNodeManageService businessNodeService;
    private final AnalysisManageManageService manageService;
    private final WorkflowBusinessManageService businessService;
    private final WorkflowBusinessUserRelManageService userRelService;
    private final TransportRolesManageService rolesManageService;
    private final ModelService modelService;
    private final AHelpManageService aHelpService;

    @Autowired
    public WFBusinessNodeController(WorkflowBusinessNodeManageService businessNodeService, AnalysisManageManageService manageService, WorkflowBusinessManageService businessService, WorkflowBusinessUserRelManageService userRelService, TransportRolesManageService rolesManageService, ModelService modelService, AHelpManageService aHelpService) {
        this.businessNodeService = businessNodeService;
        this.manageService = manageService;
        this.businessService = businessService;
        this.userRelService = userRelService;
        this.rolesManageService = rolesManageService;
        this.modelService = modelService;
        this.aHelpService = aHelpService;
    }

    //region 数据列表

    /**
     * 首页
     *
     * @param model      model模型
     * @param businessId 业务流程id
     * @return vm
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model, Integer businessId, String likeName) {

        if (businessId == null || businessId < 0) {
            throw new RuntimeException("未查询到流程业务信息");
        }

        //获取主信息
        WorkflowBusinessDTO obj = businessService.getById(businessId);
        if (obj == null) {
            throw new RuntimeException("未查询到流程业务信息");
        }

        model.addAttribute("businessObj", obj);

        WorkflowBusinessNodeDTOQuery dtoQuery = new WorkflowBusinessNodeDTOQuery();
        if (StringUtils.isNotBlank(likeName)) {
            dtoQuery.setLikeName(likeName.trim());
        }
        dtoQuery.setBusinessId(businessId);
        dtoQuery.setOrderBy("order by business_id desc, node_sort asc");
        Page<WorkflowBusinessNodeDTO> dataPage = businessNodeService.getForPage(dtoQuery);

        // 实时更新列表信息
        if (dataPage != null && dataPage.getItems().size() > 0) {
            for (WorkflowBusinessNodeDTO item : dataPage.getItems()) {
                item.setApprovalTypeName(ApprovalTypeEnum.getEnumByKey(item.getApprovalType()));
                item.setApplyTypeName(ApplyTypeEnum.getEnumByKey(item.getApplyType()));
            }
        }

        model.addAttribute("page", dataPage);
        model.addAttribute("PagePackage", PagePackage(dataPage.getPn(), dataPage.getStart(), dataPage.getPageSize(), dataPage.getTotalPages(), dataPage.getTotalItems()));
        model.addAttribute("dtoQuery", dtoQuery);

        return "basic/wfbusiness-node/index";
    }

    //详情
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    public String detail(Model model, Integer businessId) {
        if (businessId == null || businessId <= 0) {
            throw new RuntimeException("未查询到环节信息");
        }

        //获取主信息
        WorkflowBusinessDTO obj = businessService.getById(businessId);
        if (obj == null) {
            throw new RuntimeException("未查询到流程业务信息");
        }
        model.addAttribute("businessObj", obj);

        WorkflowBusinessNodeDTOQuery dtoQuery = new WorkflowBusinessNodeDTOQuery();
        dtoQuery.setBusinessId(businessId);
        dtoQuery.setOrderBy("order by business_id desc, node_sort asc");
        Page<WorkflowBusinessNodeDTO> dataPage = businessNodeService.getForPage(dtoQuery);

        for (WorkflowBusinessNodeDTO node : dataPage.getItems()) {
            node.setApprovalTypeName(ApprovalTypeEnum.getEnumByKey(node.getApprovalType()));
            node.setApplyTypeName(ApplyTypeEnum.getEnumByKey(node.getApplyType()));

            //从关联表中取出审批人信息
            WorkflowBusinessUserRelDTOQuery relQuery = new WorkflowBusinessUserRelDTOQuery();
            relQuery.setNodeId(node.getId());
            Page<WorkflowBusinessUserRelDTO> relPage = userRelService.getForPage(relQuery);
            for (WorkflowBusinessUserRelDTO item : relPage.getItems()) {
                item.setUserTypeName(ApproveUserTypeEnum.getEnumByKey(item.getUserType()));
                item.setPlayerTypeName(ApprovePlayerTypeEnum.getEnumByKey(item.getPlayerType()));
                item.setApproverTypeName(ApproverTypeEnum.getEnumByKey(item.getApproverType()));
                item.setDepName(modelService.getDepName(item.getDepId()));
                item.setApproverName(modelService.getUserTrueName(item.getApprover()));
            }
            node.setApproverList(relPage.getItems());
        }

        model.addAttribute("page", dataPage);

        return "basic/wfbusiness-node/detail";
    }

    //endregion

    //region 编辑&保存

    /**
     * 编辑
     *
     * @param model      model模型
     * @param id         主键id
     * @param businessId 流程业务id
     * @return vm
     */
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(Model model, Integer id, Integer businessId) {
        id = (id == null ? 0 : id);

        if (businessId == null || businessId <= 0) {
            throw new RuntimeException("未查询到流程业务信息");
        }

        //获取主信息
        WorkflowBusinessDTO businessObj = businessService.getById(businessId);
        if (businessObj == null) {
            throw new RuntimeException("未查询到流程业务信息");
        }

        model.addAttribute("businessObj", businessObj);

        //获取当前记录信息，设置默认值
        WorkflowBusinessNodeDTO obj;

        if (id > 0) {
            obj = businessNodeService.getById(id);

            //region 从关联表中取出审批人信息
            WorkflowBusinessUserRelDTOQuery relQuery = new WorkflowBusinessUserRelDTOQuery();
            relQuery.setNodeId(id);
            Page<WorkflowBusinessUserRelDTO> relPage = userRelService.getForPage(relQuery);
            for (WorkflowBusinessUserRelDTO item : relPage.getItems()) {
                item.setUserTypeName(ApproveUserTypeEnum.getEnumByKey(item.getUserType()));
                item.setPlayerTypeName(ApprovePlayerTypeEnum.getEnumByKey(item.getPlayerType()));
                item.setApproverTypeName(ApproverTypeEnum.getEnumByKey(item.getApproverType()));
                item.setDepName(modelService.getDepName(item.getDepId()));
                item.setRoleName(rolesManageService.getRoleName(item.getRoleId()));
                item.setApproverName(modelService.getUserTrueName(item.getApprover()));
            }
            model.addAttribute("userRelList", relPage.getItems());
            //endregion

        } else {
            obj = new WorkflowBusinessNodeDTO();
            obj.setId(id);
            obj.setApprovalType(1);
            obj.setRecordStatus(0);
            obj.setRejectStatus(-1);
            obj.setIsRejected(1);
            obj.setIsRecall(1);
            obj.setIsAdd(1);
            obj.setIsUrge(1);
            obj.setIsBack(1);
            obj.setIsCanBack(1);
            obj.setBackType(3);
            obj.setJudgeData(BigDecimal.ZERO);

            //设置最新节点顺序
            WorkflowBusinessNodeDTOQuery dtoQuery = new WorkflowBusinessNodeDTOQuery();
            dtoQuery.setBusinessId(businessId);
            dtoQuery.setOrderBy("order by node_sort desc");
            WorkflowBusinessNodeDTO lastDto = businessNodeService.getByQuery(dtoQuery);
            if (lastDto == null) {
                obj.setNodeSort(1);
            } else {
                obj.setNodeSort(lastDto.getNodeSort() + 1);
            }
        }

        model.addAttribute("Obj", obj);

        //获取管理员用户
        modelService.getManagerPage(model);

        //获取审批方式
        model.addAttribute("approvalTypeList", ApprovalTypeEnum.getEnumList());

        //审批类型
        model.addAttribute("applyTypeList", ApplyTypeEnum.getEnumList());

        //回退类型
        model.addAttribute("backTypeList", BackTypeEnum.getEnumList());

        //回退后提交
        model.addAttribute("backSubmitList", BackSubmitTypeEnum.getEnumList());

        return "basic/wfbusiness-node/edit";
    }

    /**
     * 保存 ajax异步
     *
     * @param request sevelet请求
     * @param objDTO  实体类
     * @return json
     */
    @RequestMapping(value = "/saveEdit", method = RequestMethod.POST)
    @ResponseBody
    public String saveEditNotify(HttpServletRequest request, WorkflowBusinessNodeDTO objDTO) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            if (objDTO.getIsAuto() == null) {
                objDTO.setIsAuto(0);
            }
            if (objDTO.getIsInitiatorApprover() == null) {
                objDTO.setIsInitiatorApprover(0);
            }
            if (objDTO.getIsRejected() == null) {
                objDTO.setIsRejected(0);
            }
            if (objDTO.getIsRecall() == null) {
                objDTO.setIsRecall(0);
            }
            if (objDTO.getIsJudge() == null) {
                objDTO.setIsJudge(0);
            }
            if (objDTO.getIsDriverApply() == null) {
                objDTO.setIsDriverApply(0);
            }
            if (objDTO.getIsUserApply() == null) {
                objDTO.setIsUserApply(0);
            }
            if (objDTO.getIsBack() == null) {
                objDTO.setIsBack(0);
            }
            if (objDTO.getIsCanBack() == null) {
                objDTO.setIsCanBack(0);
            }
            if (objDTO.getIsAdd() == null) {
                objDTO.setIsAdd(0);
            }
            if (objDTO.getIsUrge() == null) {
                objDTO.setIsUrge(0);
            }

            String pin = AdminBaseClass.getPin(request);
            AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

            if (objDTO.getId() == null || objDTO.getId() <= 0) {
                //新增
                //设置初始值
                objDTO.setApprover(0);
                objDTO.setApproverReplace(0);
                objDTO.setAgentId(0);
                objDTO.setAgentReplace(0);
                objDTO.setAdminId(curr_obj.getId());
                objDTO.setCreateTime(new Date());
                objDTO.setStopFlag(0);
                objDTO.setDeleteFlag(0);
                objDTO = businessNodeService.insert(objDTO);

                if (objDTO == null || objDTO.getId() <= 0) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }

            } else {
                //更新
                //将不需要更新的字段设置为NULL
                Boolean isNext = businessNodeService.updateInfoById(objDTO);

                if (!isNext) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }
            }

            //region 审批人信息关联表.保存成功后更新
            String[] f_relid = request.getParameterValues("f_relid");   //关联表的主键ID
            String[] f_usertype = request.getParameterValues("f_usertype");
            String[] f_playertype = request.getParameterValues("f_playertype");
            String[] f_approvertype = request.getParameterValues("f_approvertype");
            String[] f_depid = request.getParameterValues("f_depid");
            String[] f_roleid = request.getParameterValues("f_roleid");
            String[] f_approver = request.getParameterValues("f_approver");

            //1. 取出已保存的数据
            WorkflowBusinessUserRelDTOQuery historyQuery = new WorkflowBusinessUserRelDTOQuery();
            historyQuery.setNodeId(objDTO.getId());
            historyQuery.setStopFlag(0);
            historyQuery.setPageSize(1000);
            Page<WorkflowBusinessUserRelDTO> historyPage = userRelService.getForPage(historyQuery);

            //2. 保存到数据库
            if (f_relid != null && f_relid.length > 0) {

                List<Integer> newRelIds = new ArrayList<>(); //提交上来的，已保存过的ID
                WorkflowBusinessUserRelDTO insert;

                for (int i = 0; i < f_relid.length; i++) {
                    insert = new WorkflowBusinessUserRelDTO();
                    insert.setId(0);
                    insert.setBusinessId(objDTO.getBusinessId());
                    insert.setNodeId(objDTO.getId());
                    insert.setUserType(Integer.parseInt(f_usertype[i]));     //人员类型
                    insert.setPlayerType(Integer.parseInt(f_playertype[i])); //人员角色

                    //角色类型：1指定成员 2申请人 3复核人 4直属上级 5部门主管 6部门成员 7角色
                    int atype = Integer.parseInt(f_approvertype[i]);
                    insert.setApproverType(atype);

                    //A、如果角色类型【不是】：部门负责人或指定部门负责人，那么部门ID设为0
                    if (atype == 5 || atype == 6) {
                        insert.setDepId(Integer.parseInt(f_depid[i]));
                    } else {
                        insert.setDepId(0);
                    }

                    //B、如果角色类型【不是】：角色，那么角色ID设为0（在生成流程的时候赋值）
                    if (atype == 7) {
                        insert.setRoleId(Integer.parseInt(f_roleid[i]));
                    } else {
                        insert.setRoleId(0);
                    }

                    //C、如果角色类型【不是】：指定人员，那么审批人员要设为0（在生成流程的时候赋值）
                    if (atype == 1) {
                        insert.setApprover(Integer.parseInt(f_approver[i]));
                    } else {
                        insert.setApprover(0);
                    }

                    insert.setAdminId(curr_obj.getId());
                    insert.setCreateTime(new Date());
                    insert.setStopFlag(0);
                    insert.setDeleteFlag(0);

                    //更新或插入
                    int id = Integer.parseInt(f_relid[i]);
                    if (id > 0) {
                        //更新
                        newRelIds.add(id);
                        insert.setId(id);
                        userRelService.updateInfoById(insert);
                    } else {
                        //插入
                        userRelService.insert(insert);
                    }
                }

                //3.不存在新列表中的则表示已经删除了
                for (WorkflowBusinessUserRelDTO item : historyPage.getItems()) {
                    if (!newRelIds.contains(item.getId())) {
                        userRelService.delete(item.getId());
                    }
                }

            }
            //endregion

            //操作成功 结果返回
            map = OperateCode.CompositionResult(map, 1);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }
    //endregion

    //region 删除&改变状态

    /**
     * 通过id删除 ajax异步
     *
     * @param id 记录id
     * @return json
     */
    @RequestMapping(value = "/deleteById", method = RequestMethod.POST)
    @ResponseBody
    public String deleteNotify(Integer id) {

        // 结果返回结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        if (id == null || id <= 0) {
            map = OperateCode.CompositionResult(map, -10, "请选择要删除的记录！");
            result = JSONUtils.toJSON(map);
            return result;
        }

        try {
            Boolean isNext = businessNodeService.delete(id);
            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }

    /**
     * 状态改变 ajax异步
     *
     * @param id     记录id
     * @param status 状态
     * @return json
     */
    @RequestMapping(value = "/changeFlag", method = RequestMethod.POST)
    @ResponseBody
    public String openOrStopFlag(Integer id, Integer status) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            Boolean isNext = businessNodeService.changeState(id, status);
            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }

    //endregion

    //region 获取审批人相关数据
    @RequestMapping(value = "/selectApprover", method = RequestMethod.POST)
    public String selectApprover(Model model, Integer relId) {

        if (relId == null || relId < 0) {
            relId = 0;
        }

        WorkflowBusinessUserRelDTO dto = new WorkflowBusinessUserRelDTO();
        dto.setId(0);
        dto.setApprover(0);

        if (relId > 0) {
            dto = userRelService.getById(relId);
        }
        model.addAttribute("UserRelObj", dto);

        //用户类型
        model.addAttribute("userTypeList", ApproveUserTypeEnum.getEnumList());

        //人员类型
        model.addAttribute("playerTypeList", ApprovePlayerTypeEnum.getEnumList());

        //角色类型
        model.addAttribute("approverTypeList", ApproverTypeEnum.getEnumList());

        //部门列表
        modelService.getDepList(model);

        //角色列表
        model.addAttribute("rolesList", rolesManageService.getForList());

        return "basic/wfbusiness-node/approve-select-model";
    }
    //endregion

    //region 获取审批人信息
    @RequestMapping(value = "/getApproveUser", method = RequestMethod.POST)
    public String GetApproveUser(Model model, Integer nodeId) {
        if (nodeId != null && nodeId > 0) {
            WorkflowBusinessNodeDTO obj = businessNodeService.getById(nodeId);
            model.addAttribute("nodeTitle", obj == null ? "未知" : obj.getNodeTitle());

            //region 从关联表中取出审批人信息
            WorkflowBusinessUserRelDTOQuery relQuery = new WorkflowBusinessUserRelDTOQuery();
            relQuery.setNodeId(nodeId);
            Page<WorkflowBusinessUserRelDTO> relPage = userRelService.getForPage(relQuery);
            for (WorkflowBusinessUserRelDTO item : relPage.getItems()) {
                item.setUserTypeName(ApproveUserTypeEnum.getEnumByKey(item.getUserType()));
                item.setPlayerTypeName(ApprovePlayerTypeEnum.getEnumByKey(item.getPlayerType()));
                item.setApproverTypeName(ApproverTypeEnum.getEnumByKey(item.getApproverType()));
                item.setDepName(modelService.getDepName(item.getDepId()));
                item.setApproverName(modelService.getUserTrueName(item.getApprover()));
            }
            model.addAttribute("userRelPage", relPage);
            //endregion

        }

        return "basic/wfbusiness-node/approve-user-modal";
    }
    //endregion

}